package com.hxkj.service.impl;

import com.hxkj.dao.AdvertisementColumnDao;
import com.hxkj.dao.AdvertisementDao;
import com.hxkj.domain.enums.ColumnExceptionEnum;
import com.hxkj.domain.po.Advertisement;
import com.hxkj.domain.po.AdvertisementColumn;
import com.hxkj.domain.po.AdvertisementColumnTree;
import com.hxkj.service.AdvertisementColumnService;
import com.platform.common.domain.exception.CustomMessageException;
import com.platform.common.domain.result.ResultDataStruct;
import com.platform.common.domain.result.ResultMessageStruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ColumnServiceImpl
 * @Description
 * @Author chenfangzhou
 * @Date 2018/6/7 12:00
 * @Version 1.0
 */

@Service
@Slf4j
public class AdvertisementColumnServiceImpl implements AdvertisementColumnService {

    @Autowired
    private AdvertisementColumnDao advertisementColumnDao;

    @Autowired
    private AdvertisementDao advertisementDao;

    /**
     * 增加广告分类
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct saveColumn(AdvertisementColumn column) throws Exception {
        ResultDataStruct resultDataStruct = new ResultDataStruct();
        try {
            // 对比column名称是否已存在
            AdvertisementColumn advert = new AdvertisementColumn();
            advert.setColumnName(column.getColumnName());
            advert.setSiteId(column.getSiteId());
            if (advertisementColumnDao.get(advert).size() != 0) {
                resultDataStruct.setCode(401);
                resultDataStruct.setMessage("该分类已存在!");
                return resultDataStruct;
            }
            advertisementColumnDao.save(column);
            resultDataStruct.setData(column);
            resultDataStruct.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            resultDataStruct.setCode(ColumnExceptionEnum.COLUMN_SAVE_ERROE.getCode());
            resultDataStruct.setMessage(ColumnExceptionEnum.COLUMN_SAVE_ERROE.getMsg());
        }
        return resultDataStruct;
    }

    /**
     * 获取广告分类树结构列表
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public List<AdvertisementColumnTree> getColumnTreeList(AdvertisementColumn column) throws Exception {
        List<AdvertisementColumnTree> columnTreeList = new ArrayList<AdvertisementColumnTree>();
        try {
            column.setDelTag(0);
            // 递归调用获取分类的树结构
            columnTreeList = initTree(-1, column);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取分类失败");
        }
        return columnTreeList;
    }

    /**
     * 软删除
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public ResultMessageStruct removeColumn(AdvertisementColumn column) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            String[] columnIds = column.getColumnIds().split(",");
            for (int i = 0; i < columnIds.length; i++) {
                Long columnId = Long.valueOf(columnIds[i]);
                resultMessageStruct = checkRemove(columnId, column.getSiteId());
                if (resultMessageStruct.getCode() != 200) {
                    return resultMessageStruct;
                }
                AdvertisementColumn advertisementColumn = new AdvertisementColumn();
                advertisementColumn.setSiteId(column.getSiteId());
                advertisementColumn.setColumnId(columnId);
                advertisementColumn.setDelTag(1);
                advertisementColumnDao.update(advertisementColumn);
            }
            resultMessageStruct.setCode(200);
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 修改分分类
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public ResultMessageStruct modifyColumn(AdvertisementColumn column) throws Exception {
        ResultMessageStruct result = new ResultMessageStruct();
        try {

            // 如果修改名称,检查修改的名称是否重复
            if (StringUtils.isNotBlank(column.getColumnName())) {
                AdvertisementColumn column_ = new AdvertisementColumn();
                column_.setColumnId(column.getColumnId());
                column_.setSiteId(column.getSiteId());
                column_.setColumnName(column.getColumnName());
                List<AdvertisementColumn> list = advertisementColumnDao.checkRepeat(column_);
                if (list.size() > 0) {
                    result.setCode(401);
                    result.setMessage("分类名称已存在!");
                    return result;
                }
            }
            advertisementColumnDao.update(column);
            // 如果修改分类的可用/禁用状态,同步修改其所有子类的分类状态
            if (column.getStatus() != null) {
                // 修改子类分类状态
                modifyChildrenStatus(column.getColumnId(), column.getStatus(), column.getSiteId());
            }
            result.setCode(200);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 修改子分类的禁用状态
     *
     * @param columnId
     * @param status
     * @param siteId
     */
    private void modifyChildrenStatus(Long columnId, Integer status, Long siteId) {
        AdvertisementColumn column = new AdvertisementColumn();
        column.setParentColumnId(columnId);
        column.setSiteId(siteId);
        // 根据id来查询父节点是否有他
        List<AdvertisementColumn> list = advertisementColumnDao.get(column);
        if (null == list || list.size() == 0) {
            return;
        }
        for (AdvertisementColumn col : list) {
            col.setStatus(status);
            advertisementColumnDao.update(col);
            modifyChildrenStatus(col.getColumnId(), status, col.getSiteId());
        }
    }

    /**
     * 修改分类的排序
     *
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public ResultMessageStruct modifySortNum(Map<String, Object> map) throws Exception {
        ResultMessageStruct result = new ResultMessageStruct();
        try {
            AdvertisementColumn column = new AdvertisementColumn();
            String[] id = map.get("columnIds").toString().split(",");
            column.setSiteId(Long.parseLong(map.get("siteId").toString()));
            for (int i = 0; i < id.length; i++) {
                column.setColumnId(Long.parseLong(id[i]));
                column.setSortNumber((long) i);
                advertisementColumnDao.update(column);
            }
            result.setCode(200);
        } catch (NumberFormatException e) {
            e.printStackTrace();
            result.setCode(401);
            result.setMessage(e.getMessage());
        }
        return result;
    }


    /**
     * 删除分类前,判断分类下是否关联子级分类或者广告
     *
     * @param columnId
     * @param siteId
     * @return
     * @throws Exception
     */
    private ResultMessageStruct checkRemove(Long columnId, Long siteId) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        // 如果分类为父节点则无法删除
        AdvertisementColumn advertisementColumn = new AdvertisementColumn();
        advertisementColumn.setSiteId(siteId);
        advertisementColumn.setParentColumnId(columnId);
        if (advertisementColumnDao.get(advertisementColumn).size() != 0) {
            resultMessageStruct.setCode(401);
            resultMessageStruct.setMessage("id为" + columnId + "的分类有子级分类,无法直接删除!");
            return resultMessageStruct;
        }
        // 如果分类有关联则无法删除
        Advertisement advertisement = new Advertisement();
        advertisement.setSiteId(siteId);
        advertisement.setColumnId(columnId);
        if (advertisementDao.get(advertisement).size() != 0) {
            resultMessageStruct.setCode(401);
            resultMessageStruct.setMessage("id为" + columnId + "的分类有广告关联,无法直接删除!");
            return resultMessageStruct;
        }
        resultMessageStruct.setCode(200);
        return resultMessageStruct;
    }

    /**
     * 递归调用获取分类的树结构
     *
     * @param id
     * @param col
     * @return
     * @throws Exception
     */
    private List<AdvertisementColumnTree> initTree(long id, AdvertisementColumn col) throws Exception {
        List<AdvertisementColumnTree> columnTreeList = new ArrayList<AdvertisementColumnTree>();
        AdvertisementColumn column = new AdvertisementColumn();
        column.setParentColumnId(id);
        column.setSiteId(col.getSiteId());
        column.setStatus(col.getStatus());
        column.setDelTag(0);
        List<AdvertisementColumn> columnList = advertisementColumnDao.get(column);
        if (columnList != null && columnList.size() != 0) {
            for (AdvertisementColumn auf : columnList) {
                AdvertisementColumnTree columnTree = new AdvertisementColumnTree();
                setColTree(auf, columnTree);

                // 递归调用
                columnTree.setChildren(initTree(auf.getColumnId(), auf));

                columnTreeList.add(columnTree);
            }
        }
        return columnTreeList;
    }

    /**
     * 获取子级分类
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public List<AdvertisementColumn> getChildren(AdvertisementColumn column) throws Exception {

        AdvertisementColumn col = new AdvertisementColumn();
        col.setSiteId(column.getSiteId());
        col.setParentColumnId(column.getColumnId());
        List<AdvertisementColumn> columnList = new ArrayList<>();
        try {
            col.setDelTag(0);
            columnList = advertisementColumnDao.get(col);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取分类失败");
        }
        return columnList;
    }

    /**
     * 获取单条分类
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public AdvertisementColumn getColumn(AdvertisementColumn column) throws Exception {
        try {
            column = advertisementColumnDao.get(column.getColumnId());
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取一条分类错误");
        }
        return column;
    }

    private AdvertisementColumnTree addParentColumn(AdvertisementColumn co) throws Exception {
        AdvertisementColumnTree columnTree = new AdvertisementColumnTree();
        setColTree(co, columnTree);
        // 递归调用
        columnTree.setChildren(initTree(co.getColumnId(), co));
        return columnTree;
    }

    private void setColTree(AdvertisementColumn co, AdvertisementColumnTree columnTree) {
        columnTree.setColumnName(co.getColumnName() == null ? "" : co.getColumnName());
        columnTree.setColumnId(co.getColumnId());
        columnTree.setParentColumnId(co.getParentColumnId());
        columnTree.setSortNumber(co.getSortNumber());
        columnTree.setComment(co.getComment() == null ? "" : co.getComment());
        columnTree.setImgUrl(co.getImgUrl() == null ? "" : co.getImgUrl());
        columnTree.setSiteId(co.getSiteId());
        columnTree.setCreateTime(co.getCreateTime());
        columnTree.setUpdateTime(co.getUpdateTime());
        columnTree.setColumnTemplateId(co.getColumnTemplateId());
        columnTree.setDetailTemplateId(co.getDetailTemplateId());
        columnTree.setStatus(co.getStatus());
        columnTree.setManuscriptPath(co.getManuscriptPath());
    }


    /**
     * 获取顶级父类
     *
     * @param parentColumnId
     * @return
     * @throws Exception
     */
    private AdvertisementColumn getColumnByParentId(long parentColumnId) throws Exception {
        AdvertisementColumn co = advertisementColumnDao.get(parentColumnId);
        if (co.getParentColumnId() != -1) {
            getColumnByParentId(co.getParentColumnId());
        }
        return co;
    }

    /**
     * 获取广告分类的面包屑
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public synchronized List<AdvertisementColumn> getTopParentColumn(AdvertisementColumn column) throws Exception {
        globalColumnList.clear();
        globalColumnList = getParentColumn(column.getColumnId());
        return globalColumnList;
    }

    private List<AdvertisementColumn> globalColumnList = new ArrayList<>();

    private List<AdvertisementColumn> getParentColumn(Long columnId) throws Exception {
        AdvertisementColumn newcolumn = new AdvertisementColumn();
        AdvertisementColumn column = advertisementColumnDao.get(columnId);
        if (column == null && columnId != -2) {
            throw new CustomMessageException(402, "请配置正确的分类,查询到的分类id为" + columnId + "不在该站点下!");
        }
        newcolumn.setColumnId(column.getColumnId());
        newcolumn.setColumnName(column.getColumnName());
        newcolumn.setManuscriptPath(column.getManuscriptPath());
        globalColumnList.add(newcolumn);
        if (column.getParentColumnId() != -1) {
            getParentColumn(column.getParentColumnId());
        }
        return globalColumnList;
    }


    /**
     * 获取广告分类,不带树形结构
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct<List<AdvertisementColumn>> getColumnList(AdvertisementColumn column) throws Exception {
        ResultDataStruct<List<AdvertisementColumn>> listResultDataStruct = new ResultDataStruct<List<AdvertisementColumn>>();
        try {
            column.setDelTag(0);
            listResultDataStruct.setData(advertisementColumnDao.get(column));
            listResultDataStruct.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return listResultDataStruct;
    }


    /**
     * 获取所有的广告分类
     *
     * @param column
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct<List<AdvertisementColumn>> getAllColumnList(AdvertisementColumn column) throws Exception {
        ResultDataStruct<List<AdvertisementColumn>> listResultDataStruct = new ResultDataStruct<List<AdvertisementColumn>>();
        try {
            List<AdvertisementColumn> columnList = new ArrayList<>();
            listResultDataStruct.setData(this.initTree(column.getColumnId(), column, columnList));
            listResultDataStruct.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return listResultDataStruct;
    }


    /**
     * 初始化树结构
     *
     * @param id
     * @param col
     * @param columnList
     * @return
     * @throws Exception
     */
    private List<AdvertisementColumn> initTree(long id, AdvertisementColumn col, List<AdvertisementColumn> columnList) throws Exception {
        AdvertisementColumn column = new AdvertisementColumn();
        column.setParentColumnId(id);
        column.setSiteId(col.getSiteId());
        column.setDelTag(0);
        column.setStatus(col.getStatus());
        List<AdvertisementColumn> columnListData = advertisementColumnDao.get(column);
        if (columnListData != null && columnListData.size() != 0) {
            for (AdvertisementColumn auf : columnListData) {
                if (auf.getParentColumnId().equals(col.getColumnId())) {
                    initTree(auf.getColumnId(), auf, columnList);
                }
                columnList.add(auf);
            }
        }
        return columnList;
    }

    /**
     * 树结构的模糊查询
     * 根据任一分类,查找该分类所在的完整的树结构
     *
     * @param column
     * @return
     */
    @Override
    public List<AdvertisementColumnTree> getColumnTreeListByKeyword(AdvertisementColumn column) {
        List<AdvertisementColumnTree> columnTreeList = new ArrayList<>();
        try {
            column.setDelTag(0);
            List<AdvertisementColumn> columnList = advertisementColumnDao.get(column);
            for (AdvertisementColumn col : columnList) {
                AdvertisementColumnTree columnTree = new AdvertisementColumnTree();
                int count = 0;//Mr.zheng:定义控制器，判断是否添加了重复的父节点
                if (col.getParentColumnId() != -1) {
                    // 递归调用获取顶级父节点ID
                    AdvertisementColumn co = getColumnByParentId(col.getParentColumnId());
                    // 根据顶级父节点ID封装
                    columnTree = addParentColumn(co);
                    for (AdvertisementColumnTree columnTree1 : columnTreeList) {
                        if (columnTree1.getColumnId() == columnTree.getColumnId()) {
                            count++;
                            break;
                        }
                    }
                    if (count == 0) {
                        columnTreeList.add(columnTree);
                    }
                } else {
                    // 根据顶级父节点ID封装
                    columnTree = addParentColumn(col);
                    for (AdvertisementColumnTree columnTree1 : columnTreeList) {
                        if (columnTree1.getColumnId() == columnTree.getColumnId()) {
                            count++;
                            break;
                        }
                    }
                    if (count == 0) {
                        columnTreeList.add(columnTree);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取文章分类错误");
        }
        return columnTreeList;
    }

}
